package org.flexthinker.binding.form
{
    import org.flexthinker.binding.value.ValueModel;

    /**
     * <p>
     * A formModel groups valueModels and actions that are related to the same
     * backing object. It will manage the creation/handling of the valueModels,
     * and an overall state.
     * </p>
     *
     * <p>
     * The formModel can be in one of three 'user' states (but this is not implements currently ):
     * <ul>
     * <li><em>Disabled:</em> all user interaction should be ignored.</li>
     * <li><em>Enabled and readOnly:</em> user may interact, but not edit.</li>
     * <li><em>Enabled and editable:</em> user may interact and edit where needed.</li>
     * </ul>
     * </p>
     *
     * <p>
     * The formModel also tracks its inner states:
     * <ul>
     * <li><em>Dirty:</em> one of its valueModels has a changed value.</li>
     * <li><em>Committable:</em> all valueModels are in an 'error-free' state.</li>
     * </ul>
     * </p>
     */
    public interface FormModel
    {
        /**
         * Returns the id that is used to identify this form model.
         */
        function getId():String;

        /**
         * Returns the object currently backing this form.
         */
        function getFormObject():Object;

        /**
         * Sets the object currently backing this form.
         */
        function setFormObject(value:Object):void;

        /**
         * Returns a value model that holds the value of the specified form
         * property.
         */
        function getValueModel(formProperty:String):ValueModel;

        /**
         * Returns a type converting value model for the given form property. The
         * type of the value returned from the returned value model is guaranteed to
         * be of class targetClass.
         */
        /*function getValueModelByClass( formProperty:String,  targetClass:Class):ValueModel;*/

        /**
         * Returns true if the form has a value model for the provided property
         * name.
         */
        function hasValueModel(formProperty:String):Boolean;

        /**
         * Returns the fields that are used by this formModel. Each field has an
         * associated ValueModel.
         */
        function getFieldNames():Vector.<String>;

        /**
         * Register converters for a given property name.
         *
         * @param propertyName name of property on which to register converters
         * @param toConverter Convert from source to target type
         * @param fromConverter Convert from target to source type
         */
        //function registerPropertyConverter(propertyName:String, toConverter:Converter, fromConverter:Converter):void;

        /**
         * Commits any changes buffered by the form property value models into the
         * current form backing object.
         *
         * @see #isCommittable()
         */
        function commit():void;

        /**
         * Reverts any dirty value models back to the original values that were
         * loaded from the current form backing object since last call to either
         * commit or revert or since the last change of the form backing object.
         */
        function revert():void;

        /**
         * Returns true if the changes held by this form are able to be committed. A
         * form is committable when it and it's child form models have no validation
         * errors.
         */
        function isCommittable():Boolean;

        /**
         * Does this form model buffer changes?
         */
        function isBuffered():Boolean;

        /**
         * Returns true if any of the value models holding properties of this form
         * have been modified since the last call to either commit or revert or
         * since the last change of the form backing object.
         */
        function isDirty():Boolean;

    }
}